package heap

import "jvmgo/ch09/classfile"

type MethodRef struct {
    MemberRef
    method *Method
}

func newMethodRef(cp *ConstantPool, refInfo *classfile.ConstantMethodrefInfo) *MethodRef {
    ref := &MethodRef{}
    ref.cp = cp
    ref.copyMemberRefInfo(&refInfo.ConstantMemberrefInfo)
    return ref
}

func (self *MethodRef) ResolvedMethod() *Method {
    if self.method == nil {
        self.resolveMethodRef()
    }
    return self.method
}

// jvms8 5.4.3.3
func (self *MethodRef) resolveMethodRef() {
    d := self.cp.class
    //得到类C
    c := self.ResolvedClass()
    if c.IsInterface() {
        panic("java.lang.IncompatibleClassChangeError")
    }

    //根据方法名和描述符查找方法
    method := lookupMethod(c, self.name, self.descriptor)
    if method == nil {
        panic("java.lang.NoSuchMethodError")
    }

    //判断读取权限
    if !method.isAccessibleTo(d) {
        panic("java.lang.IllegalAccessError")
    }

    self.method = method
}

func lookupMethod(class *Class, name, descriptor string) *Method {

    method := LookupMethodInClass(class, name, descriptor)
    if method == nil {
        method = lookupMethodInInterfaces(class.interfaces, name, descriptor)
    }
    return method
}